﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

namespace AntikCompta
{
    public partial class Import : Form
    {
        private bool mImportOk;
        private String mFichier;
        public Import(String aFichierRoot)
        {
            InitializeComponent();
            mImportOk = false;
            mFichier = aFichierRoot;

            String serveur = "", login = "", password = "";
            cb_modif.Checked = !LoadConfig(ref serveur, ref login, ref password);

            txt_serveur.Text = serveur;
            txt_login.Text = login;
            txt_pass.Text = password;

            
            String fichier = DateTime.Now.ToShortDateString();
            fichier = "compta_" + fichier.Replace("/", "_");
            txt_nom.Text = fichier;

            UpdateModif();
        }

        private bool LoadConfig(ref String aServeur, ref String aLogin, ref String aPassword)
        {
            return ( (Tools.GetConfig("Serveur", out aServeur)) && 
                (Tools.GetConfig("Login", out aLogin)) && 
                (Tools.GetConfig("MotDePasse", out aPassword)) );
        }

        public bool ImportOk
        {
            get { return mImportOk; }
        }

        public String Fichier
        {
            get { return mFichier; }
        }

        private void bt_fermer_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void bt_test_Click(object sender, EventArgs e)
        {
            if (!TesterConnection(txt_serveur.Text, txt_login.Text, txt_pass.Text))
                return;

            Tools.SetConfig("Serveur", txt_serveur.Text);
            Tools.SetConfig("Login", txt_login.Text);
            Tools.SetConfig("MotDePasse", txt_pass.Text);

            bt_importer.Enabled = true;
            bt_exporter.Enabled = File.Exists(mFichier);
        }

        private bool GetRequest(String aServeur, String aLogin, String aPassword, out FtpWebRequest aRequest)
        {
            return GetRequest(aServeur, aLogin, aPassword, "", out aRequest);
        }

        private bool GetRequest(String aServeur, String aLogin, String aPassword, String aPath, out FtpWebRequest aRequest)
        {
            aRequest = null;
            Uri serverUri = new Uri("ftp://" + aLogin + "@" + aServeur + aPath);
            // The serverUri parameter should start with the ftp:// scheme.
            if (serverUri.Scheme != Uri.UriSchemeFtp)
                return false;

            aRequest = (FtpWebRequest)WebRequest.Create(serverUri);
            // On s'authentifie sur le serveur FTP
            aRequest.Credentials = new NetworkCredential(aLogin, aPassword);

            return true;
        }

        private bool TesterConnection(String aServeur, String aLogin, String aPassword)
        {
            FtpWebRequest request;
            if( !GetRequest(aServeur, aLogin, aPassword, out request) )
                return false;

            // On défini le type de requête
            request.Method = WebRequestMethods.Ftp.ListDirectory;
           
            try
            {
                // On recupere la response du serveur FTP
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                response.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }

            return true;
        }

        private void bt_importer_Click(object sender, EventArgs e)
        {
            mImportOk = false;

            EnableButton(false);

            String serveur="", login="", password="";
            if (!LoadConfig(ref serveur, ref login, ref password))
            {
                MessageBox.Show("Les paramètres de connection ne sont pas valide");
            }
            else
            {
                String fichier;
                if (!RecupererDonnees(serveur, login, password, out fichier))
                    MessageBox.Show("Impossible d'importer les données");
                else
                {
                    if (Decompresser(fichier))
                    {
                        MessageBox.Show("Les données ont été correctement importées");
                        mImportOk = true;
                    }
                }
            }

            EnableButton(true);
        }

        private bool Decompresser(String aFichier)
        {
            String rep = Sauvergarder();

            if (!File.Exists(aFichier))
                return false;

            if ( Directory.Exists(rep) )
                Directory.Delete(rep, true);

            Directory.CreateDirectory(rep);

            FastZip z = new FastZip();
            z.CreateEmptyDirectories = true;
            z.ExtractZip(aFichier, rep, "");

            mFichier = Path.Combine(rep, "compta.xml");

            File.Delete(aFichier);

            return true;
        }

        private String Sauvergarder()
        {
            String rep;
            if (!File.Exists(mFichier))
            {
                rep = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                rep = Path.Combine(rep, "comptabilite");
                return rep;
            }

            rep = Path.GetDirectoryName(mFichier);

            String fichier = DateTime.Now.ToShortDateString();
            fichier = "compta_" + fichier.Replace("/", "_");
            fichier += ".bak";
            fichier = Path.Combine(Path.GetDirectoryName(rep), fichier);

            if (File.Exists(fichier))
                File.Delete(fichier);

            FastZip z = new FastZip();
            z.CreateEmptyDirectories = true;
            z.CreateZip(fichier, rep, true, "");

            return Path.GetDirectoryName(mFichier);
        }

        private bool RecupererDonnees(String aServeur, String aLogin, String aPassword, out String aFichier)
        {
            aFichier = "";
            if (lv_fichiers.SelectedItems.Count<=0)
            {
                MessageBox.Show("Aucun fichier n'est sélectionné");
                return false;
            }

            String fichier = lv_fichiers.SelectedItems[0].Text;


            FtpWebRequest request;
            if (!GetRequest(aServeur, aLogin, aPassword, "/" + fichier, out request))
                return false;

            request.Method = WebRequestMethods.Ftp.DownloadFile;

            try
            {
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                Stream responseStream = response.GetResponseStream();

                aFichier = Path.Combine(GetApplicationRep(), fichier);

                if (File.Exists(aFichier))
                    File.Delete(aFichier);

                FileStream outputStream = new FileStream(aFichier, FileMode.Create);

                long cl = response.ContentLength;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[2048];

                readCount = responseStream.Read(buffer, 0, bufferSize);
                while (readCount > 0)
                {
                    outputStream.Write(buffer, 0, readCount);
                    readCount = responseStream.Read(buffer, 0, bufferSize);
                }

                responseStream.Close();
                outputStream.Close();
                response.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }

            return true;
        }

        private void bt_exporter_Click(object sender, EventArgs e)
        {
            if (txt_nom.Text.Length <= 0)
            {
                MessageBox.Show("Le nom de la sauvegarde doit être rensigné");
                return;
            }

            EnableButton(false);

            String fichier = PreparerDonnees(txt_nom.Text);

            String serveur = "", login = "", password = "";
            if (!LoadConfig(ref serveur, ref login, ref password))
            {
                MessageBox.Show("Les paramètres de connection ne sont pas valide");
            }
            else
            {
                if (!EnvoyerDonnees(fichier, serveur, login, password))
                    MessageBox.Show("Impossible d'exporter les données");
                else
                    MessageBox.Show("Les données ont été correctement exportées");
            }

            EnableButton(true);

            if (File.Exists(fichier))
                File.Delete(fichier);
        }

        private void EnableButton(bool aEnable)
        {
            bt_importer.Enabled = aEnable;
            bt_exporter.Enabled = aEnable;
            bt_fermer.Enabled = aEnable;
        }

        private bool EnvoyerDonnees(String aFichier, String aServeur, String aLogin, String aPassword)
        {
            if (!File.Exists(aFichier))
                return false;

            FtpWebRequest request;
            if (!GetRequest(aServeur, aLogin, aPassword, "/" + Path.GetFileName(aFichier), out request))
                return false;

            request.Method = WebRequestMethods.Ftp.UploadFile;

            try
            {
                Stream requestStream = request.GetRequestStream();

                // Copy the contents of the file to the request stream.
                byte[] fileContents = File.ReadAllBytes(aFichier);
                request.ContentLength = fileContents.Length;

                requestStream.Write(fileContents, 0, fileContents.Length);
                requestStream.Close();

                FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                response.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                EnableButton(true);
                return false;
            }

            return true;
        }

        private String GetApplicationRep()
        {
            String rep = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AntikCompta");
            if (!Directory.Exists(rep))
                Directory.CreateDirectory(rep);

            return rep;
        }

        private string PreparerDonnees(String aNom)
        {
            String rep = GetApplicationRep();

            String fichier = aNom + ".zip";
            fichier = Path.Combine(rep, fichier);           

            if (File.Exists(fichier))
                File.Delete(fichier);

            FastZip z = new FastZip();
            z.CreateEmptyDirectories = true;
            z.CreateZip(fichier, Path.GetDirectoryName(mFichier), true, "");

            return fichier;
        }

        private void bt_lister_Click(object sender, EventArgs e)
        {
            EnableButton(false);

            String serveur = "", login = "", password = "";
            if (!LoadConfig(ref serveur, ref login, ref password))
            {
                MessageBox.Show("Les paramètres de connection ne sont pas valide");
            }
            else
            {
                if (!ListerFichiers(serveur, login, password))
                    MessageBox.Show("Impossible de lister les sauvegardes");
            }

            EnableButton(true);
        }

        private bool ListerFichiers(String aServeur, String aLogin, String aPassword)
        {
            lv_fichiers.Items.Clear();

            FtpWebRequest request;
            if (!GetRequest(aServeur, aLogin, aPassword, out request))
                return false;

            // On défini le type de requête
            request.Method = WebRequestMethods.Ftp.ListDirectory;

            try
            {
                // On recupere la response du serveur FTP
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                // On récupere le flux de la réponse
                StreamReader monStreamReader = new StreamReader(response.GetResponseStream(), Encoding.Default);
                //On enregistre la liste dans un chaine
                string listeBrute = monStreamReader.ReadToEnd();
                //On recupere l'ensemble des fichiers de la chaine
                string[] liste = listeBrute.Split(Environment.NewLine.ToCharArray());

                response.Close();

                foreach (String f in liste)
                {
                    if( f.EndsWith(".zip") )
                        lv_fichiers.Items.Add(f);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }

            return true;
        }

        private void UpdateModif()
        {
            txt_serveur.Enabled = cb_modif.Checked;
            txt_login.Enabled = cb_modif.Checked;
            txt_pass.Enabled = cb_modif.Checked;
        }

        private void cb_modif_CheckedChanged(object sender, EventArgs e)
        {
            UpdateModif();
        }

        private void bt_suppr_Click(object sender, EventArgs e)
        {
            String serveur = "", login = "", password = "";
            if (!LoadConfig(ref serveur, ref login, ref password))
            {
                MessageBox.Show("Les paramètres de connection ne sont pas valide");
            }
            else
            {
                Supprimer(serveur, login, password);
                ListerFichiers(serveur, login, password);
            }
        }

        private bool Supprimer(String aServeur, String aLogin, String aPassword)
        {
            if (lv_fichiers.SelectedItems.Count <= 0)
            {
                MessageBox.Show("Aucun fichier n'est sélectionné");
                return false;
            }

            String fichier = lv_fichiers.SelectedItems[0].Text;


            FtpWebRequest request;
            if (!GetRequest(aServeur, aLogin, aPassword, "/" + fichier, out request))
                return false;

            request.Method = WebRequestMethods.Ftp.DeleteFile;

            try
            {
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
            return true;
        }

        private void cb_suppr_CheckedChanged(object sender, EventArgs e)
        {
            bt_suppr.Enabled = cb_suppr.Checked;
        }


    }
}
